#include "../../core/device/device.h"
#include "camera.h"

namespace sleek
{
    namespace node
    {
        namespace camera
        {
            Camera::Camera(core::device::Device *dev) : screen(dev)
            {
                frust = new Frustum();

                fars  = 2500.f;
                nears = 0.1f;
                fovs  =  45.f;
                asps  = (core::f32)screen->getInfo().size.width/(core::f32)screen->getInfo().size.height;
                setViewPort(core::math::aabbox2di(0, 0, screen->getInfo().size.width, screen->getInfo().size.height));
                mode = CVM_PERSPECTIV;
//                mode = CVM_ORTHOGRAPHIC;
                update();
            }
            Camera::~Camera()
            {
                delete frust;
            }
            bool Camera::manage(core::device::input*)
            {
            }

            void Camera::setFovValue(core::f32 i)
            {
                fovs = i;
            }
            void Camera::setFarValue(core::f32 i)
            {
                fars = i;
            }
            void Camera::setNearValue(core::f32 i)
            {
                nears = i;
            }
            void Camera::setAspectRatio(core::f32 i)
            {
                asps = i;
            }
            void Camera::setViewMode(CAMERA_VIEW_MODE i)
            {
                mode = i;
            }
            void Camera::setTarget(core::math::vector3df i)
            {
                tar = i;
                updateLookAtVector();
            }
            void Camera::setPosition(core::math::vector3df i)
            {
                pos = i;
                updateLookAtVector();
            }
            void Camera::setRotation(core::math::vector3df i)
            {
                rot = i;
                updateLookAtVector();
            }
            void Camera::setViewPort(core::math::aabbox2di i)
            {
                viewport = i;
                glViewport(i.getUpperLeft().width, i.getUpperLeft().height, i.getLowerRight().width, i.getLowerRight().height);
            }

            core::math::aabbox2di Camera::getViewPort()
            {
                return viewport;
            }
            core::math::vector3df Camera::getPosition()
            {
                return pos;
            }
            core::math::vector3df Camera::getRotation()
            {
                return rot;
            }
            core::math::vector3df Camera::getTarget()
            {
                return tar;
            }
            CAMERA_VIEW_MODE Camera::getViewMode()
            {
                return mode;
            }
            Frustum* Camera::getViewFrustum()
            {
                return frust;
            }
            core::f32 Camera::getAspectRatio()
            {
                return asps;
            }
            core::f32 Camera::getNearValue()
            {
                return nears;
            }
            core::f32 Camera::getFarValue()
            {
                return fars;
            }
            core::f32 Camera::getFovValue()
            {
                return fovs;
            }

            void Camera::render()
            {
            }
            void Camera::update()
            {
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                    mode != CVM_ORTHOGRAPHIC ? gluPerspective(fovs, asps, nears, fars) :
                    glOrtho(0, screen->getInfo().size.width, screen->getInfo().size.height, 0, nears, fars);
                    gluLookAt(eye.x, eye.y, eye.z, cen.x, cen.y, -cen.z, up.x,  up.y,  up.z);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
            }
            void Camera::updateLookAtVector()
            {
                eye = pos;
                cen = tar;
                up = rot.normalise();
            }
        }
    }
}
